package net.gooduo.spring_boot_template.aspect;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
@Log4j2
public class LogAspect {
    @Pointcut("execution(public * net.gooduo.spring_boot_template.controller..*.*(..)) " +
            "&& !execution(public * net.gooduo.spring_boot_template.controller.admin.AuthController.login(..))")
    public void controllerMethod() { }

    @Before("controllerMethod()")
    public void LogRequestInfo(JoinPoint joinPoint) throws Exception{
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        StringBuilder requestLog = new StringBuilder();
        Signature signature = joinPoint.getSignature();
        requestLog
                .append(((MethodSignature) signature).getMethod().getAnnotation(ApiOperation.class).value()).append("\t")
                .append("URL = ").append(request.getRequestURI()).append("\t")
                .append("METHOD = ").append(request.getMethod()).append("\t")
                .append("IP = ").append(request.getRemoteAddr()).append("\t")
                .append("CLASS_METHOD = ").append(signature.getDeclaringTypeName()).append("\t")
                .append(signature.getName()).append("\t");

        String[] paramNames = ((MethodSignature) signature).getParameterNames();
        Object[] paramValues = joinPoint.getArgs();
        int paramLength  = null == paramNames ? 0 : paramNames.length;

        if (paramLength == 0) {
            requestLog.append("params = []");
        } else {
            requestLog.append("params = [");
            for (int i = 0; i < paramLength; i++) {
                String value = "";
                if (paramValues[i] instanceof Integer) {
                    value = ((Integer) paramValues[i]).toString();
                } else if (paramValues[i] instanceof  Enum) {
                    value = paramValues[i].toString();
                }else {
                    value = JSONUtil.toJsonStr(paramValues[i]);
                }
                requestLog.append(paramNames[i]).append("=").append(value);
                if (i < paramLength - 1) {
                    requestLog.append(",");
                }
            }
            requestLog.append("]\t");
        }

        // 登录用户的信息
        requestLog.append("USER = ");
//        if (request.getRequestURI().startsWith("/api") && StpUserUtil.isLogin()) {
//            requestLog.append("user/").append(StpUserUtil.getLoginId());
//        } else
        if (request.getRequestURI().startsWith("/admin") && StpUtil.isLogin()) {
            requestLog.append("admin/").append(StpUtil.getLoginId());
        } else {
            requestLog.append("未登录");
        }
        requestLog.append("\t");

        log.info(requestLog.toString());
    }
}
